#include "market_data/ctp_md_interface.h"
#include "market_data/market_data_types.h"
#include <iostream>
#include <cstring>
#include <thread>
#include <chrono>

namespace hft {

/**
 * @brief CTP行情接口构造函数
 * 
 * @param frontAddr 前置服务器地址
 * @param brokerId 经纪商代码
 * @param userId 用户账号
 * @param password 密码
 * 
 * 初始化CTP行情接口，创建API实例并注册SPI和前置地址
 */
CtpMdInterface::CtpMdInterface(const std::string& frontAddr, 
                             const std::string& brokerId,
                             const std::string& userId, 
                             const std::string& password)
    : m_frontAddress(frontAddr),
      m_brokerID(brokerId),
      m_userID(userId),
      m_password(password),
      m_pMdApi(nullptr),
      m_isConnected(false),
      m_requestID(0) {
    // 创建API实例
    m_pMdApi = CThostFtdcMdApi::CreateFtdcMdApi("./md_flow/");
    m_pMdApi->RegisterSpi(this);
    m_pMdApi->RegisterFront(const_cast<char*>(m_frontAddress.c_str()));
}

CtpMdInterface::~CtpMdInterface() {
    if (m_pMdApi) {
        m_pMdApi->Release();
        m_pMdApi = nullptr;
    }
}

bool CtpMdInterface::connect() {
    if (!m_pMdApi) {
        if (m_errorCallback) {
            m_errorCallback("CTP API not initialized");
        }
        spdlog::error("Failed to connect: CTP API not initialized");
        return false;
    }
    
    spdlog::info("Initializing CTP market data connection...");
    m_pMdApi->Init();
    return true;
}

void CtpMdInterface::disconnect() {
    if (m_api && m_connected) {
        spdlog::info("Disconnecting from CTP market data server...");
        CThostFtdcUserLogoutField logoutField = {};
        strncpy(logoutField.BrokerID, m_brokerId.c_str(), sizeof(logoutField.BrokerID));
        strncpy(logoutField.UserID, m_userId.c_str(), sizeof(logoutField.UserID));
        m_api->ReqUserLogout(&logoutField, ++m_requestId);
    }
}

bool CtpMdInterface::subscribe(const std::vector<std::string>& symbols) {
    if (!m_connected || !m_api) {
        spdlog::error("Failed to subscribe: Not connected to CTP server");
        return false;
    }

    spdlog::info("Subscribing to {} instruments", symbols.size());

    // 转换合约列表为CTP需要的格式
    char* insts[symbols.size()];
    for (size_t i = 0; i < symbols.size(); ++i) {
        insts[i] = const_cast<char*>(symbols[i].c_str());
    }

    int ret = m_api->SubscribeMarketData(insts, symbols.size());
    return ret == 0;
}

bool CtpMdInterface::unsubscribe(const std::vector<std::string>& symbols) {
    if (!m_connected || !m_api) {
        if (m_logCallback) {
            m_logCallback("Failed to unsubscribe: Not connected to CTP server");
        }
        return false;
    }

    spdlog::info("Unsubscribing from {} instruments", symbols.size());

    // 转换合约列表为CTP需要的格式
    char* insts[symbols.size()];
    for (size_t i = 0; i < symbols.size(); ++i) {
        insts[i] = const_cast<char*>(symbols[i].c_str());
    }

    int ret = m_api->UnSubscribeMarketData(insts, symbols.size());
    return ret == 0;
}

// CTP回调接口实现
void CtpMdInterface::OnFrontConnected() {
    if (m_logCallback) {
        m_logCallback("CTP front connection established");
    }
    m_connected = true;
    
    // 连接成功后立即登录
    CThostFtdcReqUserLoginField loginField = {};
    strncpy(loginField.BrokerID, m_brokerId.c_str(), sizeof(loginField.BrokerID));
    strncpy(loginField.UserID, m_userId.c_str(), sizeof(loginField.UserID));
    strncpy(loginField.Password, m_password.c_str(), sizeof(loginField.Password));
    
    m_api->ReqUserLogin(&loginField, ++m_requestId);
}

void CtpMdInterface::OnFrontDisconnected(int nReason) {
    if (m_logCallback) {
        std::string msg = "CTP front disconnected, reason: " + std::to_string(nReason);
        m_logCallback(msg);
    }
    m_connected = false;
    
    if (m_errorCallback) {
        std::string msg = "CTP connection lost, reason: " + std::to_string(nReason);
        m_errorCallback(msg);
    }
    
    // 自动重连逻辑
    if (m_autoReconnect) {
        std::this_thread::sleep_for(std::chrono::seconds(5));
        if (m_api) {
            m_api->Init();
        }
    }
}

void CtpMdInterface::OnRspUserLogin(CThostFtdcRspUserLoginField *pRspUserLogin, 
                                   CThostFtdcRspInfoField *pRspInfo, 
                                   int nRequestID, bool bIsLast) {
    if (m_logCallback) {
        if (pRspInfo && pRspInfo->ErrorID != 0) {
            std::string msg = "CTP login failed, ErrorID: " + std::to_string(pRspInfo->ErrorID) +
                             ", ErrorMsg: " + (pRspInfo->ErrorMsg ? pRspInfo->ErrorMsg : "");
            m_logCallback(msg);
        } else {
            m_logCallback("CTP login successful");
        }
    }

    if (pRspInfo && pRspInfo->ErrorID != 0) {
        if (m_errorCallback) {
            m_errorCallback(pRspInfo->ErrorMsg);
        }
        return;
    }
    
    // 登录成功后的处理
    if (m_dataCallback) {
        MarketData data;
        data.type = MarketData::LOGIN;
        data.timestamp = std::chrono::system_clock::now();
        m_dataCallback(data);
    }
}

void CtpMdInterface::OnRspSubMarketData(CThostFtdcSpecificInstrumentField *pSpecificInstrument, 
                                       CThostFtdcRspInfoField *pRspInfo, 
                                       int nRequestID, bool bIsLast) {
    if (pRspInfo && pRspInfo->ErrorID != 0) {
        if (m_errorCallback) {
            m_errorCallback(pRspInfo->ErrorMsg);
        }
    }
}

void CtpMdInterface::OnHeartBeatWarning(int nTimeLapse) {
    // 心跳警告，表示连接可能有问题
    if (m_logCallback) {
        std::string level = (nTimeLapse > 10) ? "WARNING" : "INFO";
        std::string msg = "CTP heartbeat " + level + ", time lapse: " + 
                         std::to_string(nTimeLapse) + " seconds";
        m_logCallback(msg);
    }
    
    if (m_errorCallback) {
        std::string msg = "CTP heartbeat warning, time lapse: " + std::to_string(nTimeLapse) + " seconds";
        m_errorCallback(msg);
    }
    
    // 如果超过30秒没有心跳，尝试重连
    if (nTimeLapse > 30 && m_autoReconnect) {
        disconnect();
        connect();
    }
}

void CtpMdInterface::OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketData) {
    if (!pDepthMarketData) {
        return;
    }

    if (m_logCallback) {
        std::string msg = "Market data update: " + std::string(pDepthMarketData->InstrumentID) + 
                         " LastPrice=" + std::to_string(pDepthMarketData->LastPrice) +
                         " Volume=" + std::to_string(pDepthMarketData->Volume);
        m_logCallback(msg);
    }

    if (!m_dataCallback) {
        return;
    }
    
    MarketData data;
    data.type = MarketData::DEPTH;
    data.symbol = pDepthMarketData->InstrumentID;
    data.lastPrice = pDepthMarketData->LastPrice;
    data.volume = pDepthMarketData->Volume;
    data.openInterest = pDepthMarketData->OpenInterest;
    data.timestamp = std::chrono::system_clock::now();
    
    // 买卖盘数据
    for (int i = 0; i < 5; ++i) {
        data.bidPrices[i] = pDepthMarketData->BidPrice[i];
        data.bidVolumes[i] = pDepthMarketData->BidVolume[i];
        data.askPrices[i] = pDepthMarketData->AskPrice[i];
        data.askVolumes[i] = pDepthMarketData->AskVolume[i];
    }
    
    m_dataCallback(data);
}